home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / a_utils / perl / perl5a1.lha / perl5alpha1 / do / sprintf < prev    next >
Encoding:
Text File  |  1992-08-15  |  4.0 KB  |  198 lines

  1. void
  2. do_sprintf(TARG,len,sarg)
  3. register STR *TARG;
  4. register int len;
  5. register STR **sarg;
  6. {
  7.     register char *s;
  8.     register char *t;
  9.     register char *f;
  10.     bool dolong;
  11. #ifdef QUAD
  12.     bool doquad;
  13. #endif /* QUAD */
  14.     char ch;
  15.     register char *send;
  16.     register STR *arg;
  17.     char *xs;
  18.     int xlen;
  19.     int pre;
  20.     int post;
  21.     double value;
  22.  
  23.     str_set(TARG,"");
  24.     len--;            /* don't count pattern string */
  25.     t = s = str_get(*sarg);
  26.     send = s + (*sarg)->str_cur;
  27.     sarg++;
  28.     for ( ; ; len--) {
  29.  
  30.     /*SUPPRESS 560*/
  31.     if (len <= 0 || !(arg = *sarg++))
  32.         arg = &str_no;
  33.  
  34.     /*SUPPRESS 530*/
  35.     for ( ; t < send && *t != '%'; t++) ;
  36.     if (t >= send)
  37.         break;        /* end of format string, ignore extra args */
  38.     f = t;
  39.     *buf = '\0';
  40.     xs = buf;
  41. #ifdef QUAD
  42.     doquad =
  43. #endif /* QUAD */
  44.     dolong = FALSE;
  45.     pre = post = 0;
  46.     for (t++; t < send; t++) {
  47.         switch (*t) {
  48.         default:
  49.         ch = *(++t);
  50.         *t = '\0';
  51.         (void)sprintf(xs,f);
  52.         len++, sarg--;
  53.         xlen = strlen(xs);
  54.         break;
  55.         case '0': case '1': case '2': case '3': case '4':
  56.         case '5': case '6': case '7': case '8': case '9': 
  57.         case '.': case '#': case '-': case '+': case ' ':
  58.         continue;
  59.         case 'l':
  60. #ifdef QUAD
  61.         if (dolong) {
  62.             dolong = FALSE;
  63.             doquad = TRUE;
  64.         } else
  65. #endif
  66.         dolong = TRUE;
  67.         continue;
  68.         case 'c':
  69.         ch = *(++t);
  70.         *t = '\0';
  71.         xlen = (int)str_gnum(arg);
  72.         if (strEQ(f,"%c")) { /* some printfs fail on null chars */
  73.             *xs = xlen;
  74.             xs[1] = '\0';
  75.             xlen = 1;
  76.         }
  77.         else {
  78.             (void)sprintf(xs,f,xlen);
  79.             xlen = strlen(xs);
  80.         }
  81.         break;
  82.         case 'D':
  83.         dolong = TRUE;
  84.         /* FALL THROUGH */
  85.         case 'd':
  86.         ch = *(++t);
  87.         *t = '\0';
  88. #ifdef QUAD
  89.         if (doquad)
  90.             (void)sprintf(buf,s,(quad)str_gnum(arg));
  91.         else
  92. #endif
  93.         if (dolong)
  94.             (void)sprintf(xs,f,(long)str_gnum(arg));
  95.         else
  96.             (void)sprintf(xs,f,(int)str_gnum(arg));
  97.         xlen = strlen(xs);
  98.         break;
  99.         case 'X': case 'O':
  100.         dolong = TRUE;
  101.         /* FALL THROUGH */
  102.         case 'x': case 'o': case 'u':
  103.         ch = *(++t);
  104.         *t = '\0';
  105.         value = str_gnum(arg);
  106. #ifdef QUAD
  107.         if (doquad)
  108.             (void)sprintf(buf,s,(unsigned quad)value);
  109.         else
  110. #endif
  111.         if (dolong)
  112.             (void)sprintf(xs,f,U_L(value));
  113.         else
  114.             (void)sprintf(xs,f,U_I(value));
  115.         xlen = strlen(xs);
  116.         break;
  117.         case 'E': case 'e': case 'f': case 'G': case 'g':
  118.         ch = *(++t);
  119.         *t = '\0';
  120.         (void)sprintf(xs,f,str_gnum(arg));
  121.         xlen = strlen(xs);
  122.         break;
  123.         case 's':
  124.         ch = *(++t);
  125.         *t = '\0';
  126.         xs = str_get(arg);
  127.         xlen = arg->str_cur;
  128.         if (*xs == 'S' && xs[1] == 't' && xs[2] == 'B' && xs[3] == '\0'
  129.           && xlen == sizeof(STBP)) {
  130.             STR *tmpstr = Str_new(24,0);
  131.  
  132.             stab_efullname(tmpstr, ((STAB*)arg)); /* a stab value! */
  133.             sprintf(tokenbuf,"*%s",tmpstr->str_ptr);
  134.                     /* reformat to non-binary */
  135.             xs = tokenbuf;
  136.             xlen = strlen(tokenbuf);
  137.             str_free(tmpstr);
  138.         }
  139.         if (strEQ(f,"%s")) {    /* some printfs fail on >128 chars */
  140.             break;        /* so handle simple cases */
  141.         }
  142.         else if (f[1] == '-') {
  143.             char *mp = index(f, '.');
  144.             int min = atoi(f+2);
  145.  
  146.             if (mp) {
  147.             int max = atoi(mp+1);
  148.  
  149.             if (xlen > max)
  150.                 xlen = max;
  151.             }
  152.             if (xlen < min)
  153.             post = min - xlen;
  154.             break;
  155.         }
  156.         else if (isDIGIT(f[1])) {
  157.             char *mp = index(f, '.');
  158.             int min = atoi(f+1);
  159.  
  160.             if (mp) {
  161.             int max = atoi(mp+1);
  162.  
  163.             if (xlen > max)
  164.                 xlen = max;
  165.             }
  166.             if (xlen < min)
  167.             pre = min - xlen;
  168.             break;
  169.         }
  170.         strcpy(tokenbuf+64,f);    /* sprintf($s,...$s...) */
  171.         *t = ch;
  172.         (void)sprintf(buf,tokenbuf+64,xs);
  173.         xs = buf;
  174.         xlen = strlen(xs);
  175.         break;
  176.         }
  177.         /* end of switch, copy results */
  178.         *t = ch;
  179.         STR_GROW(TARG, TARG->str_cur + (f - s) + xlen + 1 + pre + post);
  180.         str_ncat(TARG, s, f - s);
  181.         if (pre) {
  182.         repeatcpy(TARG->str_ptr + TARG->str_cur, " ", 1, pre);
  183.         TARG->str_cur += pre;
  184.         }
  185.         str_ncat(TARG, xs, xlen);
  186.         if (post) {
  187.         repeatcpy(TARG->str_ptr + TARG->str_cur, " ", 1, post);
  188.         TARG->str_cur += post;
  189.         }
  190.         s = t;
  191.         break;        /* break from for loop */
  192.     }
  193.     }
  194.     str_ncat(TARG, s, t - s);
  195.     STABSET(TARG);
  196. }
  197.  
  198.